<?php

namespace App\Http\ControllersVer1;

use Illuminate\Http\Request;

use Requests;
use Carbon\Carbon;
use Webpatser\Uuid\Uuid;
use Namshi\JOSE\SimpleJWS;

use WxPay\WxPayApi;
use WxPay\WxPayConfig;
use WxPay\WxPayUnifiedOrder;
use WxPay\WxPayJsApiPay;

use App\User;

class WxController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    //
    public function test() {
        return response()->json([
            'code' => 2000,
            'msg' => 'api v1 test success!'
        ]);

    }



    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function obtainOpenid(Request $request) {

        $this->validate($request, [
            'code' => 'required'
        ]);

        $js_code = $request->input('code');

        //SkyLibrary
        $app_id = 'wx03d5b8742cdab615';
        $app_secret = '10e799067b4f21444a32e615c66cd06e';

        $url = "https://api.weixin.qq.com/sns/jscode2session";
        $url .= "?appid=".$app_id;
        $url .= "&secret=".$app_secret;
        $url .= "&js_code=".$js_code;
        $url .= "&grant_type=authorization_code";

        $response = Requests::get($url);

        $ret_array = json_decode($response->body, true);

        if (array_key_exists('errcode', $ret_array)) {
            //
            return response('Unauthorized.', 401);
        }

        //else to get openid
        $openid = $ret_array['openid'];

        return response()->json([
            'openid' => $openid,
            'msg' => 'success'
        ]);

    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function makePayment(Request $request) {

        $this->validate($request, [
            'openid' => 'required'
        ]);

        $openid = $request->input('openid');

        return response()->json([
            'code' => 2000,
            'msg' => 'success!'
        ]);

    }


    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function seedPayment(Request $request) {

        $this->validate($request, [
            'openid' => 'required',
            'fee' => 'required|integer|min:1'
        ]);
        $openid = $request->input("openid");
        $fee = $request->input("fee");

        $orderInput = new WxPayUnifiedOrder();

        $orderInput->SetAppid("wx03d5b8742cdab615");
        //mch_id
        //nonce_str
        //sign
        $orderInput->SetBody("打赏");
        $orderInput->SetDetail("支持创办天空图书馆，为早日上线加油！");
        //$order->SetAttach("test");
        $orderInput->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
        $orderInput->SetTotal_fee($fee);
        //spbill_create_ip
        $orderInput->SetNotify_url("http://www.weixin.qq.com/wxpay/pay.php");
        $orderInput->SetTrade_type("JSAPI");
        $orderInput->SetOpenid($openid);

        $order = WxPayApi::unifiedOrder($orderInput);

        //
        if(!array_key_exists("appid", $order)
            || !array_key_exists("prepay_id", $order)
            || $order['prepay_id'] == "")
        {
            throw new WxPayException("参数错误");
        }

        $jsapi = new WxPayJsApiPay();
        $jsapi->SetAppid($order["appid"]);
        //set appid is needed for right paySign...
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $order['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $payargs = $jsapi->GetValues();

        return response()->json([
            'code' => 2000,
            'payargs' => $payargs,
            'msg' => 'success!'
        ]);

    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function levelsPayment(Request $request) {

        $this->validate($request, [
            'openid' => 'required',
            'fee' => 'required|integer|min:1'
        ]);
        $openid = $request->input("openid");
        $fee = $request->input("fee");

        $orderInput = new WxPayUnifiedOrder();

        $orderInput->SetAppid("wx03d5b8742cdab615");
        //mch_id
        //nonce_str
        //sign
        $orderInput->SetBody("升级");
        $orderInput->SetDetail("增加级别");
        //$order->SetAttach("test");
        $orderInput->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
        $orderInput->SetTotal_fee($fee);
        //spbill_create_ip
        $orderInput->SetNotify_url("http://www.weixin.qq.com/wxpay/pay.php");
        $orderInput->SetTrade_type("JSAPI");
        $orderInput->SetOpenid($openid);

        $order = WxPayApi::unifiedOrder($orderInput);

        //
        if(!array_key_exists("appid", $order)
            || !array_key_exists("prepay_id", $order)
            || $order['prepay_id'] == "")
        {
            throw new WxPayException("参数错误");
        }

        $jsapi = new WxPayJsApiPay();
        $jsapi->SetAppid($order["appid"]);
        //set appid is needed for right paySign...
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $order['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $payargs = $jsapi->GetValues();

        return response()->json([
            'code' => 2000,
            'payargs' => $payargs,
            'msg' => 'success!'
        ]);

    }



    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function makeOrder(Request $request) {

        $this->validate($request, [
            'openid' => 'required',
            'order_body' => 'required',
            'order_detail' => 'required',
            'fee' => 'required|integer|min:1'
        ]);

        $openid = $request->input("openid");
        $order_body = $request->input("order_body");
        $order_detail = $request->input("order_detail");
        $fee = $request->input("fee");

        $order_number = WxPayConfig::MCHID.date("YmdHis");

        $orderInput = new WxPayUnifiedOrder();

        $orderInput->SetAppid("wx03d5b8742cdab615");
        //mch_id
        //nonce_str
        //sign
        $orderInput->SetBody($order_body);
        $orderInput->SetDetail($order_detail);
        //$order->SetAttach("test");
        $orderInput->SetOut_trade_no($order_number);
        $orderInput->SetTotal_fee($fee);
        //spbill_create_ip
        $orderInput->SetNotify_url("http://www.weixin.qq.com/wxpay/pay.php");
        $orderInput->SetTrade_type("JSAPI");
        $orderInput->SetOpenid($openid);

        $order = WxPayApi::unifiedOrder($orderInput);

        //
        if(!array_key_exists("appid", $order)
            || !array_key_exists("prepay_id", $order)
            || $order['prepay_id'] == "")
        {
            throw new WxPayException("参数错误");
        }

        $jsapi = new WxPayJsApiPay();
        $jsapi->SetAppid($order["appid"]);
        //set appid is needed for right paySign...
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $order['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $payargs = $jsapi->GetValues();

        return response()->json([
            'code' => 2000,
            'payargs' => $payargs,
            'order_number' => $order_number,
            'msg' => 'success!'
        ]);

    }




    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function login(Request $request) {

        $this->validate($request, [
            'code' => 'required'
        ]);

        $js_code = $request->input('code');

        //SkyLibrary
        $app_id = 'wx03d5b8742cdab615';
        $app_secret = '10e799067b4f21444a32e615c66cd06e';

        $url = "https://api.weixin.qq.com/sns/jscode2session";
        $url .= "?appid=".$app_id;
        $url .= "&secret=".$app_secret;
        $url .= "&js_code=".$js_code;
        $url .= "&grant_type=authorization_code";

        $response = Requests::get($url);

        $ret_array = json_decode($response->body, true);

        if (array_key_exists('errcode', $ret_array)) {
            //
            return response()->json([
                'code' => 40600,
                'msg' => $ret_array['errmsg']
            ]);
        }

        //else to get openid
        $xcx_openid = $ret_array['openid'];

        //session_key is for https://mp.weixin.qq.com/debug/wxadoc/dev/api/signature.html?t=20161122
        //$session_key = $ret_array['session_key'];
        //expires_in is seconds
        //$expires_in = $ret_array['expires_in'];

        //Redis::set('test:xcx:user_id', json_encode(['session_key' => $session_key, 'openid' => $openid ]));

        //$api_token = '';

        //$rawData = '';
        //$signature2 = sha1( $rawData + $session_key );

        //register or get the User id
        $user = User::where('xcx_openid', $xcx_openid)->first();

        //already registered.
        if ($user == null) {
            return response()->json([
                'code' => 40600,
                'msg' => 'xcx not binded.'
            ]);
        }

        //
        $jws = new SimpleJWS(array(
            'alg' => 'HS256'
        ));

        $jws->setPayload(array(
            'uid' => $user->id,
            'exp' => Carbon::now()->addDay(30)->getTimestamp(),
            //Carbon::now()->addMinutes(3)->getTimestamp(),
        ));

        $secretKey = env('JWT_KEY');
        $jws->sign($secretKey);
        $api_token = $jws->getTokenString();
        //
        return response()->json([
            'code' => 2000,
            'api_token' => $api_token,
            'me' => $user,
            'mobile' => $user->mobile,
            'msg' => 'success'
        ]);

    }





    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function bindMobile(Request $request) {

        $this->validate($request, [
            'mobile' => 'required|digits:11',
            'js_code' => 'required',
            'sms_code' => 'required|digits:6'
        ]);


        //
        $mobile = $request->input('mobile');
        $prefix_code = "86";
        $sms_code = $request->input('sms_code');

        //todo: ...
        $code_saved = "123456";

        if ($sms_code != $code_saved) {
            return response()->json([
                'code' => 40600,
                'msg' => 'wrong sms code.'
            ]);
        }

        //
        $js_code = $request->input('js_code');

        //SkyLibrary
        $app_id = 'wx03d5b8742cdab615';
        $app_secret = '10e799067b4f21444a32e615c66cd06e';

        $url = "https://api.weixin.qq.com/sns/jscode2session";
        $url .= "?appid=".$app_id;
        $url .= "&secret=".$app_secret;
        $url .= "&js_code=".$js_code;
        $url .= "&grant_type=authorization_code";

        $response = Requests::get($url);

        $ret_array = json_decode($response->body, true);

        if (array_key_exists('errcode', $ret_array)) {
            //
            return response()->json([
                'code' => 40600,
                'msg' => $ret_array['errmsg']
            ]);
        }
        //else to get openid
        $xcx_openid = $ret_array['openid'];

        //
        $user = User::where('xcx_openid', $xcx_openid)->first();
        if (!is_null($user)) {
            if ($user->mobile != $mobile) {
                $user->xcx_openid = "";
                $user->save();
            }
        }

        //
        $user = User::where('mobile', $mobile)->first();
        if (is_null($user)) {
            //register new user
            $user = new User;
            $user->uuid = str_replace('-', '', Uuid::generate(4)->string);
            $user->mobile = $mobile;
        }
        //bind the xcx openid to the user of the mobile
        $user->xcx_openid = $xcx_openid;
        $user->save();

        //
        $jws = new SimpleJWS(array(
            'alg' => 'HS256'
        ));

        $jws->setPayload(array(
            'uid' => $user->id,
            'exp' => Carbon::now()->addDay(30)->getTimestamp(),
            //Carbon::now()->addMinutes(3)->getTimestamp(),
        ));

        $secretKey = env('JWT_KEY');
        $jws->sign($secretKey);
        $api_token = $jws->getTokenString();

        return response()->json([
            'code' => 2000,
            'api_token' => $api_token,
            'me' => $user,
            'mobile' => $user->mobile,
            'msg' => 'bind mobile success.'
        ]);
    }




    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function unbindMobile(Request $request) {

        $me = $request->user();

        $me->xcx_openid = "";
        $me->save();

        return response()->json([
            'code' => 2000,
            'msg' => "success.",
        ]);
    }



    //------------ user
    /**
     * @param Request $request
     * @param $user_uuid
     * @return \Illuminate\Http\JsonResponse
     */
    public function showUser(Request $request, $user_uuid) {

        if (strlen($user_uuid) != 32) {
            return response()->json([
                'code' => 4060,
                'msg' => 'wrong user uuid!'
            ]);
        }

        $user = User::where('uuid', $user_uuid)->first();

        if (is_null($user)) {
            return response()->json([
                'code' => 4060,
                'msg' => 'no user!'
            ]);
        }

        $levels_count = 1;
        $stones_count = 16;

        return response()->json([
            'code' => 2000,
            'user' => $user,
            'levels_count' => $levels_count,
            'stones_count' => $stones_count,
            'msg' => 'success!'
        ]);

    }



}
